﻿using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using HPAGMRestAPIWrapper;

namespace AGMRestAPITest
{
    /// <summary>
    /// Summary description for AGMRequirementTest
    /// </summary>
    [TestClass]
    public class AGMRequirementTest
    {
        public AGMRequirementTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext _testContextInstance;

        private static AGMConnection _connection;
        private static AGMRequirements _requirements;

        private AGMRequirement _reqfolder;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return _testContextInstance;
            }
            set
            {
                _testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize]
        public static void MyClassInitialize(TestContext testContext) {
            _connection = new AGMConnection(AGMSetting.SERVERNAME, AGMSetting.USERNAME, AGMSetting.PASSWORD);
            _requirements = new AGMRequirements(_connection);
        }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        [ClassCleanup]
        public static void MyClassCleanup() {
            if (_connection != null)
                _connection.Logoff();
        }
        //
        // Use TestInitialize to run code before running each test 
        [TestInitialize]
        public void MyTestInitialize() 
        {
        }
        //
        // Use TestCleanup to run code after each test has run
        [TestCleanup]
        public void MyTestCleanup() 
        {
        }
        #endregion

        [TestMethod]
        public void Requirement_GetUserStories()
        {
            var us = _requirements.Get(1967);
        }


        [TestMethod]
        public void Requirement_UpdateDeleteFolder()
        {
            #region Update requirement folder
            _reqfolder.SetUpdateField("Description", "Updated Description");
            var updFolder = _reqfolder.Update();
            Assert.AreEqual(updFolder.GetField("Description").Value, "Updated Description", "Update requirement folder failed.");
            #endregion
        }

        [TestMethod]
        public void Requirement_AddUpdateDeleteItem()
        {
            #region add requirement item
            var fields = new Dictionary<string, string>
                             {
                                 {"description", "Description of new requirement."}
                             };

            var newReq = _reqfolder.AddRequirement("LR User Story", "New Requirement", fields);
            Assert.IsTrue(_requirements.Get(newReq.Id.Value) != null, "Add requirement fail.");
            #endregion            

            #region update requirement item
            newReq.SetUpdateField("owner", "steve");
            var updatedReq = newReq.Update();
            Assert.AreEqual(updatedReq.GetField("owner").Value, "steve", "Update requirement fail.");
            #endregion

            #region delete requirement item
            updatedReq.Delete();
            Assert.IsTrue(!_requirements.IsExists(newReq.Id.Value), "delete requirement fail.");
            #endregion  
        }

        [TestMethod]
        public void Requirement_UploadDownLoadDeleteAttachmentOnFolder()
        {
            _reqfolder.UploadAttachment(@"Test.txt");
            Assert.IsTrue(_reqfolder.IsAttachmentExists("Test.txt"), "Uploaded attachement is not exists.");

            _reqfolder.DownloadAttachment(@"Test.txt", @"c:\Test.txt");
            Assert.IsTrue(Helper.CheckAttachment(@"C:\Test.txt"), "Downloaded attachement is not exists.");

            _reqfolder.DeleteAttachment(@"Test.txt");
            Assert.IsFalse(_reqfolder.IsAttachmentExists("Test.txt"), "Uploaded attachement is not exists.");
        }

        [TestMethod]
        public void Requirement_UploadDownLoadDeleteAttachment()
        {
            #region add requirement item
            var fields = new Dictionary<string, string>
                             {
                                 {"description", "Description of new requirement."}
                             };

            var newReq = _reqfolder.AddRequirement("LR User Story", "New Requirement", fields);
            Assert.IsTrue(_requirements.Get(newReq.Id.Value) != null, "Add requirement fail.");
            #endregion

            newReq.UploadAttachment(@"Test.txt");
            Assert.IsTrue(newReq.IsAttachmentExists("Test.txt"), "Uploaded attachement is not exists.");

            newReq.DownloadAttachment(@"Test.txt", @"c:\Test.txt");
            Assert.IsTrue(Helper.CheckAttachment(@"C:\Test.txt"), "Downloaded attachement is not exists.");

            newReq.DeleteAttachment(@"Test.txt");
            Assert.IsFalse(newReq.IsAttachmentExists("Test.txt"), "Uploaded attachement is not exists.");

            #region delete requirement item
            newReq.Delete();
            Assert.IsTrue(!_requirements.IsExists(newReq.Id.Value), "delete requirement fail.");
            #endregion
        }

        [TestMethod]
        public void Requirement_GetAddDeleteDefectLinks()
        {
            #region add requirement item
            var fields = new Dictionary<string, string>
                             {
                                 {"description", "Description of new requirement."}
                             };

            var newReq = _reqfolder.AddRequirement("LR User Story","New Requirement",fields);
            Assert.IsTrue(_requirements.Get(newReq.Id.Value) != null, "Add requirement fail.");
            #endregion

            #region create some defects
            var defects = new AGMDefects(_connection);
            var bugfields = new Dictionary<string, string> {{"name", "New Defect 1"}, {"severity", "1-Low"}};
            var newd1 = defects.Create(bugfields);

            var bugfields2 = new Dictionary<string, string> {{"name", "New Defect 2"}, {"severity", "1-Low"}};
            var newd2 = defects.Create(bugfields2);
            #endregion

            newReq.LinkToDefects(new[] { newd1.Id.Value, newd2.Id.Value });
            var linkedbugs = newReq.GetLinkedDefects();
            foreach (var bug in linkedbugs)
            {
                Assert.IsTrue((bug.Id.Value == newd1.Id.Value || bug.Id.Value == newd2.Id.Value), "Added defect link does not found.");
            }

            newReq.DeleteLinkedDefects(new[] { newd1.Id.Value, newd2.Id.Value });
            var linkedbugs2 = newReq.GetLinkedDefects();
            Assert.AreEqual(linkedbugs2.Count, 0, "Delete defect links fail.");

            newd1.Delete();
            newd2.Delete();

            #region delete requirement item
            newReq.Delete();
            Assert.IsTrue(!_requirements.IsExists(newReq.Id.Value), "delete requirement fail.");
            #endregion
        }
    }
}
